package com.manyauthenticationway.server.manyauthenticationway.config.oauth2

import com.manyauthenticationway.server.manyauthenticationway.config.PasswordEncode
import com.manyauthenticationway.server.manyauthenticationway.config.handle.RedisTokenStoreHandle
import com.manyauthenticationway.server.manyauthenticationway.domain.user.SysUserService
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.context.annotation.Configuration
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer


@EnableAuthorizationServer
@Configuration
class AuthorizationServerConfig: AuthorizationServerConfigurerAdapter() {
    @Autowired
    private lateinit var sysUserService: SysUserService
    @Autowired
    private lateinit var redisTokenStoreHandle: RedisTokenStoreHandle
    @Autowired
    @Qualifier("authenticationManagerBean")
    private lateinit var authenticationManager: AuthenticationManager

    @Throws(Exception::class)
    override fun configure(endpoints: AuthorizationServerEndpointsConfigurer) {
        endpoints
                .authenticationManager(authenticationManager)//必须要有，不然密码模式无法获取token
                .userDetailsService(sysUserService)
                .tokenStore(redisTokenStoreHandle.tokenStore())
    }

    @Throws(Exception::class)
    override fun configure(clients: ClientDetailsServiceConfigurer) {
        clients.inMemory()//配置内存中，也可以是数据库
                .withClient("clientId")//clientid
                .secret(PasswordEncode().encode("clientSecret"))//不能加密，加密后无法通过认证
                .accessTokenValiditySeconds(3600)//token有效时间  秒
                .authorizedGrantTypes("refresh_token", "password", "authorization_code")//token模式
                .scopes("all")//限制允许的权限配置
    }

    override fun configure(security: AuthorizationServerSecurityConfigurer) {
        security.allowFormAuthenticationForClients()//允许表单认证
                .checkTokenAccess("permitAll()")//允许 check_token 访问
                .passwordEncoder(PasswordEncode())
    }
}